Skip to content

feat(fdc): Add execute_graphql signatures and integration test suite - #970

Open
mk2023 wants to merge 11 commits into
winefrom
barolo-seed
Open

feat(fdc): Add execute_graphql signatures and integration test suite#970
mk2023 wants to merge 11 commits into
winefrom
barolo-seed

Conversation

@mk2023

@mk2023 mk2023 commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Added execute_graphql and execute_graphql_read method signatures and docstrings to DataConnect and _DataConnectApiClient. Expanded unit test coverage in tests/test_data_connect.py for payload formatting, options validation, and error bubbling, and introduced a comprehensive integration test suite in integration/test_data_connect.py translated from Node.js Admin SDK integration tests.

mk2023 added 5 commits July 20, 2026 14:09
Implemented _make_gql_request on _DataConnectApiClient to execute and handle responses/errors for GraphQL operations. Added corresponding unit tests in tests/test_data_connect.py.
Refactored _parse_graphql_response and added robust recursive type deserialization to _DataConnectApiClient.

- Implemented _deserialize_type and _deserialize_dataclass helper methods to support nested dataclasses, generic lists (List[T]), generic dictionaries (Dict[K, V]), Unions (Union[...]), Enums, and primitive casting.
- Enhanced _make_gql_request error handling to prevent silent error swallowing when the errors key is present.
- Added comprehensive unit test coverage in tests/test_data_connect.py.
…helper

- Introduced QueryError subclass of FirebaseError for Data Connect GraphQL query/mutation errors and exposed it in __all__.
- Extracted _check_graphql_errors helper method on _DataConnectApiClient.
- Updated error handling for non-dictionary response payloads in _parse_graphql_response to raise InternalError.
- Note: Did not edit parse_graphql_response because we are waiting on whether this will even be a function or not.
…nt instantiation

- Removed output deserialization helpers (_extract_actual_type, _deserialize_type, _deserialize_dataclass) to return raw JSON payload dictionaries (ExecuteGraphqlResponse.data), aligning Data Connect with Firestore and Realtime Database patterns for user-defined schemas.
- Updated DataConnect.__init__ to immediately instantiate _DataConnectApiClient for consistency with Node.js and other Python Admin SDK services.
- Updated test suite in tests/test_data_connect.py to cover raw response parsing and immediate client instantiation.
Added execute_graphql and execute_graphql_read method signatures and docstrings to DataConnect and _DataConnectApiClient. Also introduced a comprehensive integration test suite in integration/test_data_connect.py translated from Node.js Admin SDK integration tests.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces execute_graphql and execute_graphql_read methods to the DataConnect client, along with corresponding integration and unit tests. The review feedback highlights that several of these new methods are left unimplemented (raising NotImplementedError) and provides their implementation details. Additionally, the reviewer identifies a critical type-checking bug in the validation logic when variables_type is Any, and points out a mismatch in a test assertion message.

Comment thread firebase_admin/dataconnect.py Outdated
Comment thread firebase_admin/dataconnect.py Outdated
Comment thread firebase_admin/dataconnect.py Outdated
Comment thread tests/test_data_connect.py Outdated

@stephenarosaj stephenarosaj left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in progress, leaving comments early - have to look at test cases still

Comment thread firebase_admin/dataconnect.py
Comment thread firebase_admin/dataconnect.py Outdated
Comment thread firebase_admin/dataconnect.py Outdated
Comment thread firebase_admin/dataconnect.py Outdated
Comment thread integration/test_data_connect.py Outdated
Added an explicit __init__ constructor to Impersonation to validate parameter configurations at object instantiation time. Enforced choosing either unauthenticated=True or auth_claims, with support for both auth_claims (snake_case) and authClaims (camelCase). Updated class docstring to recommend factory methods. Also added unit test suite TestImpersonation in tests/test_data_connect.py.
@mk2023
mk2023 changed the base branch from barolo to wine July 29, 2026 07:00
@mk2023
mk2023 marked this pull request as ready for review July 29, 2026 07:01
mk2023 and others added 3 commits July 29, 2026 00:12
…mulator test setup

Implemented execute_graphql and execute_graphql_read methods on DataConnect and _DataConnectApiClient. Configured Data Connect emulator schema, connector, queries, mutations, seed script, and GitHub Actions CI workflow step.

@stephenarosaj stephenarosaj left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with some changes requested - mostly small stuff, only a few blocking comments

Comment thread firebase_admin/dataconnect.py
Comment thread firebase_admin/dataconnect.py
Comment thread firebase_admin/dataconnect.py Outdated
Comment thread integration/emulators/seed.sh
Comment thread integration/test_data_connect.py Outdated
Comment thread integration/test_data_connect.py
Comment thread tests/test_data_connect.py Outdated
Comment thread tests/test_data_connect.py Outdated
Comment thread tests/test_data_connect.py Outdated
Comment thread tests/test_data_connect.py

@stephenarosaj stephenarosaj left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accidentally selected Approve but mean Request changes - re-submitting review

LGTM with some changes requested - mostly small stuff, only a few blocking comments

@mk2023
mk2023 requested a review from jonathanedey July 31, 2026 19:58
if not isinstance(auth_claims, dict):
raise ValueError("'auth_claims' must be a dictionary.")
super().__init__(authClaims=claims)
super().__init__(authClaims=auth_claims)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

think there might still be a typo here - should be auth_claims=auth_claims right?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was also confused about this, but the snake_case auth_claims is used in the __init__ signature and the authenticated() factory method so the public API remains purely Pythonic. However, because this class inherits from dict, the super().__init__(authClaims=...) is required to translate that pythonic argument into the exact camelCase authClaims JSON key that the Firebase Data Connect API expects. If we change the super().__init__ call to snake_case, the backend will reject the payload.

@stephenarosaj stephenarosaj Aug 1, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great call out - I think we should remedy this, and it shouldn't be too complex. This is how I'm thinking of it:

  • authClaims is what the backend API expects - this is how the data should be represented when it's turned into JSON and sent over the wire
  • auth_claims is the Pythonic, user-facing representation of that same data
  • If users were to print an instance of the Impersonation class at runtime, they would see authClaims - but this is the JSON representation, not the Python representation! We should instead be using the auth_claims representation here, since that's what users will interact with and it matches the platform via which they are interacting (Python)
  • We should keep the Python representation when in user-facing Python land, and use the JSON wire representation when communicating with the backend (instead of communicating with users) - this implies that we need some "translation" between the two
    • Lucky for us, we already have a _prepare_graphql_payload method which "Serializes input query and options to JSON-compatible dictionary" ;)

Comment thread tests/test_data_connect.py
Comment thread tests/test_data_connect.py
Comment thread tests/test_data_connect.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants